package com.admin.oauth;

import com.admin.common.constant.Constant;
import com.admin.common.utils.TokenUtil;
import com.admin.oauth.component.UserCacheManager;
import com.admin.oauth.dto.LoginUserDto;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @author /
 */
public class TokenFilter extends GenericFilterBean {

    private final UserCacheManager userCacheManager;

    /**
     * @param userCacheManager 用户缓存工具
     */
    public TokenFilter(UserCacheManager userCacheManager) {
        this.userCacheManager = userCacheManager;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String token = TokenUtil.get(request.getHeader(Constant.JWT_HEADER));
        // 对于 Token 为空的不需要去查 Redis
        if (StringUtils.hasText(token)) {
            String tokenMd5 = userCacheManager.tokenToMd5(token);
            LoginUserDto user = userCacheManager.getJwtUser(tokenMd5);
            if (user != null) {
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);

                // Token 续期
                userCacheManager.renewal(tokenMd5, user.getUsername());
            }
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

}
